﻿using Ice;
using Ice.Extension;
using SwitchIPModifier.Core;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SwitchIPModifier
{
    public partial class Form1 : Form
    {
        private readonly string _version = "D20251008";
        private Config _config;
        private IceSerialPort _iserialPort = new IceSerialPort();
        private bool _useConsole = false;  //是否使用Console窗口
        private string _upgradeLog = "";
        private string _applicationName;
        private Stopwatch _sw = new Stopwatch();
        private Stopwatch _totalSw = new Stopwatch();

        //OK SN
        private List<string> _passSns = new List<string>();

        private List<string> _itemValues = new List<string>();


        public Form1()
        {
            this.StartPosition = FormStartPosition.CenterScreen;
            _config = IniHelper.GetConfig();
            InitializeComponent();
            this.FormClosing += (o, e) =>
            {
                Environment.Exit(0);
            };

            _applicationName = Process.GetCurrentProcess().ProcessName + ".exe";

            if (_config.IsScanSn)
            {
                btnSetIp.Visible = false;
                lblSn.Visible = true;
                txtSn.Visible = true;
                this.ActiveControl = txtSn;
            }
            else
            {
                btnSetIp.Visible = true;
                lblSn.Visible = false;
                txtSn.Visible = false;
                this.ActiveControl = btnSetIp;
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.MinimizeBox = false;
            this.MaximizeBox = false;
            this.FormBorderStyle = FormBorderStyle.FixedSingle;
            this.toolStripStatusLabel1.Text = "软件版本:" + _version;
            this.Text = string.IsNullOrEmpty(_config.Title) ? "交换机核对信息" : _config.Title;

            if (string.IsNullOrWhiteSpace(_config.SeriapPortName))
            {
                button2.PerformClick();
            }
            else
            {
                InitSerialPort();
            }
            _sw.Start();

            LoadPassSn();
            ShowInfo("请扫描信息");



            this.ActiveControl = txtSn;

        }

        private void InitSerialPort()
        {
            _iserialPort?.Close();
            _iserialPort.PortName = _config.SeriapPortName;
            _iserialPort.BaudRate = _config.BaudRate;
            if (_useConsole)
                _iserialPort.ShowInfoToConsole(tboxPing);
            else
                _iserialPort.ShowInfoToUi(tboxPing);
            //InitSerialPipes();
            try
            {
                _iserialPort.Open();
            }
            catch (Exception ex)
            {
                MessageBox.Show("串口被占用,请检测");
                return;
            }
        }




        private void ClearSerialPrint()
        {
            if (_useConsole)
                Console.Clear();
            else
                tboxPing.InvokeText("");
        }

        private void InitSerialPipes()
        {
            _iserialPort
                .Linking(0, "U-Boot", line =>
                {
                    if (!string.IsNullOrEmpty(txtSn.Text))
                    {
                        ShowInfo("正在启动");

                    }
                    _sw.Restart();
                    this.Invoke(x =>
                    {
                        dataGridView1.Rows.Clear();
                        button2.Enabled = false;
                    });
                    _upgradeLog = "";
                    ClearSerialPrint();
                    AppendConsoleInfo($"开始时间:{DateTime.Now:yyyy-MM-dd HH:mm:ss}");
                    _totalSw.Restart();
                }).Linking(1, "stop autoboot", line =>
                {
                    if (string.IsNullOrEmpty(txtSn.Text))
                    {
                        this.Invoke(x =>
                        {
                            _iserialPort.ClearStep();
                            EnableMac();
                            MessageBox.Show("请先扫描信息");
                        });
                    }
                })
                .Linking(2, "Press any key to continue", line =>
                {
                    new Thread(CheckInfo).Start();
                })
                ;
        }


        private void AddRow(string content, string result)
        {
            _sw.Restart();
            dataGridView1.Invoke(x =>
            {
                var i = x.Rows.Count;
                x.Rows.Add(i + 1, content, result, "");
            });
        }

        private void UpdateRow(bool result)
        {
            var secord = _sw.ElapsedMilliseconds * 1.0 / 1000;
            dataGridView1.Invoke(x =>
            {
                var i = x.Rows.Count;
                x[2, i - 1].Value = result ? "✔" : "NG";
                x[2, i - 1].Style.ForeColor = result ? Color.Green : Color.Red;
                x[3, i - 1].Value = secord.ToString("0.00");
            });
        }


        private void WriteLog(string sn, string ip, bool result)
        {
            var dir = _config.LogDir;
            dir = Path.Combine(dir, Text + $"({_applicationName})", DateTime.Now.ToString("yyyyMMdd"));
            if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
            var secord = _totalSw.ElapsedMilliseconds * 1.0 / 1000;
            _totalSw.Stop();
            AddRow("总耗时", secord.ToString());
            var log = _upgradeLog + tboxPing.Text + Environment.NewLine + $"结束时间:{DateTime.Now:yyyy-MM-dd HH:mm:ss} 总耗时:{secord} 秒";
            var s = result ? "logO" : "logX";
            var name = _config.Title ?? "";
            var filename = Path.Combine(dir, $"{name}_{s}_{sn.ToMesMac()}_{DateTime.Now:yyyyMMddHHmmss}.txt");
            File.WriteAllText(filename, log);

            //csv
            if (!_config.IsScanSn) return;
            var csvDir = Path.Combine(dir, "csv日志");
            if (!Directory.Exists(csvDir)) Directory.CreateDirectory(csvDir);
            var csvFile = $"{DateTime.Now:yyyyMMdd}.csv";
            if (!File.Exists(Path.Combine(csvDir, csvFile)))
            {
                File.WriteAllText(Path.Combine(csvDir, csvFile), "No,SN,IP,Test Result " + Environment.NewLine);
            }
            var lines = File.ReadAllLines(Path.Combine(csvDir, csvFile));
            int i = lines.Length;
            File.AppendAllText(Path.Combine(csvDir, csvFile), $"{i},{sn},{ip}," + (result ? "OK" : "NG") + Environment.NewLine);
        }


        private delegate void InvokeDelegate();
        /// <summary>
        /// 同步更新UI
        /// </summary>
        /// <param name="invoke"></param>
        private void postUI(InvokeDelegate invoke)
        {
            this.Invoke(invoke);
        }


        private void txtSn_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode != Keys.Enter) return;
            if (_config.IsScanSn)
            {
                if (txtSn.Text.Length != _config.SnLength)
                {
                    MessageBox.Show("SN长度不正确,请检查!");
                    return;
                }
                var sn = txtSn.Text.Trim();
                if (_passSns.Any(w => w == sn))
                {
                    ShowInfo($"{sn}\n不能重复核对NG", false);
                    txtSn.Text = "";
                    txtSn.Focus();
                    return;
                }
            }
            ShowInfo("正在设置IP");
            txtSn.Enabled = false;
            button2.Enabled = false;
            btnSetIp.Enabled = false;
            tboxPing.Text = "";
            dataGridView1.Rows.Clear();
            Task.Run(() =>
            {
                try
                {
                    _totalSw.Restart();
                    AppendConsoleInfo($"开始时间:{DateTime.Now:yyyy-MM-dd HH:mm:ss}");
                    CheckInfo();
                }
                catch (Exception ex)
                {
                    ShowInfo(ex.ToString(), false);
                }
                finally
                {
                    EnableMac();
                    _iserialPort.ClearStep();
                }
            });
        }


        private void CheckInfo()
        {
            _itemValues.Clear();
            var sn = txtSn.Text.Trim() ?? "";
            _iserialPort.Write(13);
            Thread.Sleep(800);
            _iserialPort.Write(_config.Account);
            Thread.Sleep(800);
            _iserialPort.Write(_config.Password);
            Thread.Sleep(800);
            ShowInfo("正在设置IP");

            AddRow("设置IP:" + _config.Ip, "设置中");

            _iserialPort.Write("con");
            Thread.Sleep(400);
            _iserialPort.Write("ip add " + _config.Ip);
            Thread.Sleep(400);
            _iserialPort.Write("exit");
            Thread.Sleep(400);
            _iserialPort.Write("save");
            Thread.Sleep(400);
            _iserialPort.WriteAfterCapture("show ip");
            Thread.Sleep(2000);
            var s = _iserialPort.StopCaptrue();
            var lines = s.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
            var items = new List<string>()
            {
                "IP Address"
            };
            foreach (var item in items)
            {
                var value = "";
                foreach (var line in lines)
                {
                    if (!line.Contains(":")) continue;
                    var index = line.IndexOf(":");
                    var head = line.Substring(0, index);
                    var last = line.Substring(index + 1);
                    if (head.Trim() == item)
                    {
                        value = last.Trim().Replace(",", " ");
                        break;
                    }
                }
                _itemValues.Add(value);
            }

            var newIp = _itemValues.First();
            if (newIp.ToMesMac() != _config.Ip.ToMesMac())
            {
                AppendConsoleInfo($"检查IP {_config.Ip}\tFAIL");
                UpdateRow(false);
                ShowInfo("设置IP FAIL", false);
                _iserialPort.ClearStep();
                WriteLog(sn, newIp, false);
                EnableMac();
                return;
            }

            UpdateRow(true);

            WriteLog(sn, newIp, true);
            SavePassMac(sn);
            ShowInfo("设置IP PASS\n请更换下一块", true);
            _iserialPort.ClearStep();
            button2.Invoke(x =>
            {
                x.Enabled = true;
            });
            EnableMac();
        }

        private void EnableMac()
        {
            this.Invoke(x =>
            {
                button2.Enabled = true;
                btnSetIp.Enabled = true;
                if (_config.IsScanSn)
                {
                    txtSn.Enabled = true;
                    txtSn.Focus();
                    txtSn.SelectAll();
                }
                else
                {
                    txtSn.Text = "";
                    btnSetIp.Focus();
                }
            });
        }


        private void AppendConsoleInfo(string s)
        {
            tboxPing.Invoke(x =>
            {
                x.AppendText(Environment.NewLine + s + Environment.NewLine);
            });
        }

        private void ShowInfo(string info)
        {
            this.postUI(() =>
            {
                labShow.Text = info;
                labShow.ForeColor = Color.Black;
            });
        }

        private void ShowInfo(string info, bool flag)
        {
            this.postUI(() =>
            {
                labShow.Text = info;
                labShow.ForeColor = flag ? Color.Green : Color.Red;
            });
        }


        private void Button2_Click(object sender, EventArgs e)
        {
            var f = new ConfigForm();
            if (f.ShowDialog() == DialogResult.OK)
            {
                _config = IniHelper.GetConfig();
                RestartApp();
                return;
            }
        }

        private void SavePassMac(string sn)
        {
            if (!_config.IsScanSn) return;
            _passSns.Add(sn);
            File.AppendAllText("pass_sn.txt", $"{sn}" + "\r\n");
        }

        private void LoadPassSn()
        {
            if (!File.Exists("pass_sn.txt")) return;
            var macs = File.ReadAllLines("pass_sn.txt");
            _passSns = macs.Where(w => !string.IsNullOrEmpty(w)).ToList();
        }

        static void RestartApp()
        {
            // 获取当前执行的exe文件的路径
            string exePath = Assembly.GetExecutingAssembly().Location;

            // 启动新的进程来运行当前exe文件
            Process.Start(exePath);

            // 关闭当前进程
            Environment.Exit(0);
        }

        private void btnSetIp_Click(object sender, EventArgs e)
        {
            txtSn_KeyDown(null, new KeyEventArgs(Keys.Enter));
        }
    }
}
